package com.vincent.filepicker.ability;

import com.vincent.filepicker.Constant;
import com.vincent.filepicker.ResourceTable;
import com.vincent.filepicker.ToastUtil;
import com.vincent.filepicker.filter.FileFilter;
import com.vincent.filepicker.filter.callback.FilterResultCallback;
import com.vincent.filepicker.filter.entity.Directory;
import com.vincent.filepicker.filter.entity.ImageFile;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.app.Context;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.vincent.filepicker.ability.ImagePickAbility.DEFAULT_MAX_NUMBER;

/**
 * Created by Vincent Woo
 * Date: 2016/10/20
 * Time: 14:37
 */

public class ImageBrowserAbility extends BaseAbility {
    public static final String IMAGE_BROWSER_INIT_INDEX = "ImageBrowserInitIndex";
    public static final String IMAGE_BROWSER_SELECTED_LIST = "ImageBrowserSelectedList";
    private int mMaxNumber;
    private int mCurrentNumber = 0;
    private int initIndex = 0;
    private int mCurrentIndex = 0;

    private PageSlider mViewPager;
    private Text mTbImagePick;
    private ArrayList<ImageFile> mList = new ArrayList<>();
    private Checkbox mSelectView;
    private ArrayList<ImageFile> mSelectedFiles;
    private List<Component> mPages = new ArrayList<>();

    @Override
    public void permissionGranted() {

    }

    @Override
    public void permissionDenied() {

    }

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_vw_ability_image_browser);

        mMaxNumber = getIntent().getIntParam(Constant.MAX_NUMBER, DEFAULT_MAX_NUMBER);
        initIndex = getIntent().getIntParam(IMAGE_BROWSER_INIT_INDEX, 0);
        mCurrentIndex = initIndex;
        mSelectedFiles = getIntent().getSequenceableArrayListParam(IMAGE_BROWSER_SELECTED_LIST);
        mCurrentNumber = mSelectedFiles.size();
        loadData();
    }

    private void initView() {
        findComponentById(ResourceTable.Id_backImage).setClickedListener(component -> terminateAbility());
        findComponentById(ResourceTable.Id_confirmText).setClickedListener(component -> finishThis());

        mTbImagePick = (Text) findComponentById(ResourceTable.Id_titleText);
        mTbImagePick.setText(mCurrentNumber + "/" + mMaxNumber);

        mSelectView = (Checkbox) findComponentById(ResourceTable.Id_cbx);
        mSelectView.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component v) {
                if (!v.isSelected() && isUpToMax()) {
                    ToastUtil.getInstance(ImageBrowserAbility.this).showToast(ResourceTable.String_vw_up_to_max);
                    return;
                }

                if (v.isSelected()) {
                    mList.get(mCurrentIndex).setSelected(false);
                    mCurrentNumber--;
                    v.setSelected(false);
                    mSelectedFiles.remove(mList.get(mCurrentIndex));
                } else {
                    mList.get(mCurrentIndex).setSelected(true);
                    mCurrentNumber++;
                    v.setSelected(true);
                    mSelectedFiles.add(mList.get(mCurrentIndex));
                }

                mTbImagePick.setText(mCurrentNumber + "/" + mMaxNumber);
            }
        });

        mViewPager = (PageSlider) findComponentById(ResourceTable.Id_vp_image_pick);
        mViewPager.setPageMargin(20);
        mViewPager.setProvider(new ImageBrowserAdapter());
        mViewPager.addPageChangedListener(new PageSlider.PageChangedListener() {
            @Override
            public void onPageSliding(int i, float v, int i1) {

            }

            @Override
            public void onPageSlideStateChanged(int i) {

            }

            @Override
            public void onPageChosen(int i) {
                mCurrentIndex = i;
                mSelectView.setChecked(mList.get(mCurrentIndex).isSelected());
            }
        });

        mSelectView.setChecked(mList.get(mCurrentIndex).isSelected());
    }

    private void loadData() {
        FileFilter.getImages(this, new FilterResultCallback<ImageFile>() {
            @Override
            public void onResult(List<Directory<ImageFile>> directories) {
                mList.clear();
                for (Directory<ImageFile> directory : directories) {
                    mList.addAll(directory.getFiles());
                }
                Collections.reverse(mList);
                for (int i = 0; i < mList.size(); i++) {
                    for (int j = 0; j < mSelectedFiles.size(); j++) {
                        if (mSelectedFiles.get(j).getPath().equals(mList.get(i).getPath())) {
                            mList.get(i).setSelected(true);
                        }
                    }
                }
                initView();
                LayoutScatter scatter = LayoutScatter.getInstance(getContext());
                for (int i = 0; i < mList.size(); i++) {
                    Component component = scatter.parse(ResourceTable.Layout_item_main_preview, null, false);
                    mPages.add(component);
                    Image image = (Image) component.findComponentById(ResourceTable.Id_iv_photo_view);
                    image.setPixelMap(getPixelMapById(ImageBrowserAbility.this, mList.get(i).getId()));
                }
                mViewPager.getProvider().notifyDataChanged();
                mViewPager.setCurrentPage(initIndex);

            }
        });
    }

    public static PixelMap getPixelMapById(Context context, long id) {
        DataAbilityHelper helper = DataAbilityHelper.creator(context);
        try {
            FileDescriptor fd = helper.openFile(getUriById(id), "r");
            ImageSource imageSource = ImageSource.create(fd, null);
            PixelMap pixelMap = imageSource.createPixelmap(null);
            return pixelMap;
        } catch (DataAbilityRemoteException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Uri getUriById(long id) {
        Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(id));
        return uri;
    }

    private class ImageBrowserAdapter extends PageSliderProvider {

        @Override
        public int getCount() {
            return null == mPages ? 0 : mPages.size();
        }

        @Override
        public Object createPageInContainer(ComponentContainer componentContainer, int i) {
            componentContainer.addComponent(mPages.get(i));
            return mList.get(i);
        }

        @Override
        public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
            componentContainer.removeComponent(mPages.get(i));
        }

        @Override
        public boolean isPageMatchToObject(Component component, Object o) {
            return component == o;
        }
    }

    private boolean isUpToMax() {
        return mCurrentNumber >= mMaxNumber;
    }

    private void finishThis() {
        Intent intent = new Intent();
        intent.setSequenceableArrayListParam(Constant.RESULT_BROWSER_IMAGE, mSelectedFiles);
        setResult(RESULT_OK, intent);
        terminateAbility();
    }

    @Override
    public void onBackPressed() {
        finishThis();
    }
}
